const Koa = require("koa");
const app = new Koa();
const KoaRouter = require("koa-router");
const router = new KoaRouter();
const bodyParser = require("koa-bodyparser");

// 引入我们封装的 mysql 客户端
const query = require("./mysql");

// 定义路由表
router.get("/", async (ctx) => {
    ctx.body = "Hi, Koa ~.";
});

// 身份认证接口
router.post("/login", async (ctx) => {
    // 客户端发来请求时，我们要在此校验它的身份
    const { username, password } = ctx.request.body;
    // 根据用户名，查询数据库，看看存不存在这个用户
    let res = await query("select * from user where username = ?", [username]);
    if (res.length === 0) {
        ctx.body = {
            code: 404,
            message: "用户不存在",
        };
        return;
    }
    const user = res[0];
    // 看看这个用户的密码是否正确
    if (user.password !== password) {
        ctx.body = {
            code: 400,
            message: "密码不正确",
        };
        return;
    }
    // 返回登录成功
    ctx.body = {
        code: 200,
        data: {
            uid: user.id,
        },
        message: "登录成功",
    };
});

// get 请求方式是用来获取数据的
// context
router.get("/users", async (ctx) => {
    // 接收请求参数
    const { pagenum, pagesize, keyword } = ctx.query;
    // 传分页参数了，我们再进行分页
    if (pagenum && pagesize) {
        // 查询列的 SQL 语句
        let select_col_sql = "select * from user";
        // 查询条数
        let select_count_sql = "select count(*) as total from user";
        // 模糊查询条件
        let where_sql =
            " where username like ? or mobile like ? or email like ?";
        // 分页 SQL
        let limit_sql = " limit ?, ?";
        // 分页计算公式
        startIndex = (pagenum - 1) * pagesize;

        // 有关键词，那么就要加上关键词
        if (keyword) {
            // 列表数据
            const list = await query(select_col_sql + where_sql + limit_sql, [
                `%${keyword}%`,
                `%${keyword}%`,
                `%${keyword}%`,
                startIndex,
                Number(pagesize),
            ]);
            // 总数
            const res = await query(select_count_sql + where_sql, [
                `%${keyword}%`,
                `%${keyword}%`,
                `%${keyword}%`,
            ]);
            // 返回响应
            ctx.body = {
                code: 200,
                data: {
                    list,
                    total: res[0].total,
                },
                message: "请求成功",
            };
        } else {
            // 列表数据
            const list = await query(select_col_sql + limit_sql, [
                startIndex,
                Number(pagesize),
            ]);
            // 总数
            const res = await query(select_count_sql);
            ctx.body = {
                code: 200,
                data: {
                    list,
                    total: res[0].total,
                },
                message: "请求成功",
            };
        }
        // 没传分页参数，返回所有数据
    } else {
        const res = await query("select * from user");
        ctx.body = {
            code: 200,
            data: res,
            message: "请求成功",
        };
    }
});

router.post("/users", async (ctx) => {
    // 因为使用了 koa-bodyparse，请求体信息将被解析到 ctx.request.body 里面
    const { username, password, mobile, email } = ctx.request.body;
    // 非空检验
    if (!username || !password || !mobile || !email) {
        ctx.body = {
            code: 400,
            message: "缺少必须参数",
        };
        return;
    }
    // 校验手机号
    if (!/^1[3579]\d{9}$/.test(mobile)) {
        ctx.body = {
            code: 400,
            message: "手机号格式不正确",
        };
        return;
    }
    // 邮箱校验 531804271@qq.com
    if (!/^\w+@\w+\.com$/.test(email)) {
        ctx.body = {
            code: 400,
            message: "邮箱格式不正确",
        };
        return;
    }
    // 存入数据库
    const res = await query(
        "insert into user (username, password, mobile, email) values (?, ?, ?, ?)",
        [username, password, mobile, email]
    );
    // 判断是否添加成功
    if (res.affectedRows !== 1) {
        ctx.body = {
            code: 500,
            message: "添加失败",
        };
    } else {
        ctx.body = {
            code: 201,
            message: "添加成功",
        };
    }
});

// 修改接口
router.put("/users/:id", async (ctx) => {
    // 获取请求体参数
    const { password, mobile, email } = ctx.request.body;
    // 获取路径参数
    const { id } = ctx.params;
    // 一般我们把认证相关的信息，放在请求头中
    const uid = ctx.header.uid;
    if (!uid) {
        ctx.body = {
            code: 401,
            message: "无法识别身份，请先进行身份认证",
        };
        return;
    }
    // 判断是不是修改自己的信息
    if (id !== uid) {
        ctx.body = {
            code: 403,
            message: "你不能修改其他用户的信息",
        };
        return;
    }
    // 存在，修改用户信息
    const res = await query(
        "update user set password = ?, mobile = ?, email = ? where id = ?",
        [password, mobile, email, id]
    );
    if (res.affectedRows !== 1) {
        ctx.body = {
            code: 500,
            message: "修改失败",
        };
    } else {
        ctx.body = {
            code: 200,
            message: "修改成功",
        };
    }
});

// 删除用户
router.delete("/users/:id", async (ctx) => {
    // 判断请求头中，是否包含 uid 字段
    const uid = ctx.header.uid;
    // 接收路径参数
    const { id } = ctx.params;
    // 要删除的用户和登录时的用户不一致时，不让你删除
    if (Number(uid) !== Number(id)) {
        ctx.body = {
            code: 403,
            message: "你不能删除其他用户",
        };
        return;
    }
    // // 判断这个 id 所表示的用户存不存在
    // let res = await query("select * from user where id = ?", [id]);
    // if (res.length === 0) {
    //     ctx.body = "要删除的用户不存在";
    //     return;
    // }
    // 删除
    res = await query("delete from user where id = ?", [id]);
    if (res.affectedRows !== 1) {
        ctx.body = {
            code: 500,
            message: "删除失败",
        };
    } else {
        ctx.body = {
            code: 204,
            message: "删除成功",
        };
    }
});

// 解析请求体的中间件
app.use(bodyParser());
// 使用 router 这个中间件
app.use(router.routes());

app.listen(9000, () => {
    console.log("Koa 服务器已启动，你可以访问：http://localhost:9000");
});
